<?php

defined( 'IN_CLASS' ) or die( 'Access Error!' );

/**
 * 公共函数操作类
 */
class func {
	public static $func;
	
	/**
	 * 模板操作类
	 *
	 * @return Smarty
	 */
	public static function smarty() {
		if( !self::$func['smarty'] ) {
			include_once DIR_LIB . 'smarty/Smarty.class.php';
			self::$func['smarty'] = new Smarty(); //建立模板类
			self::$func['smarty']->template_dir = DIR_VIEW . 'chinaren/';
			self::$func['smarty']->compile_dir = DIR_DAT . 'view_c/';
			self::$func['smarty']->config_dir = DIR_DAT . 'config_c';
			self::$func['smarty']->left_delimiter    = '{*';      //开始符
		    self::$func['smarty']->right_delimiter   = '*}';     //结束符
		    self::$func['smarty']->force_compile     = false;       //强制重编译,上线后改为false
		    self::$func['smarty']->compile_check     = true;       //检查模板改动,上线后改为false
		    self::$func['smarty']->debugging         = false;          //打开调试  
		    self::$func['smarty']->debugging_ctrl    = 'URL';     //调试方法
		}
		return self::$func['smarty'];
	}
	
	/**
	 * 显示模板
	 *
	 * @param array $aOut 输出的变量
	 * @param string $template 模板文件名称
	 */
	public static function display( $aOut, $template ) {
		if( !file_exists( func::smarty()->template_dir . $template ) ) {
			die( 'System Error! Template Not Exist!' );
		}
		func::smarty()->assign(array(
		'aU' => all::$aU,
		'aOut' => $aOut,
		));
		func::smarty()->display( $template );
		exit;
	}
	
	/**
	 * 过滤所有输入的内容
	 * 不能传入对象或者数组,否则返回结果错误
	 *
	 * @param string $var 变量名或者变量
	 * @param string $type 希望得到的类型
	 * @param string $source 变量来源
	 * @param boolean $isself 是否是自身,如果为true,则直接替换$var自身
	 * @param boolean $allowhtml 是否允许HTML代码 
	 * @param boolean $sqlsafe SQL安全替换
	 * @return mix
	 */
	static function input ( $var, $type = 's', $source = 'REQUEST', $isself = false, $allowhtml = false, $sqlsafe = true ) {
		$source = in_array( $source, array( 'GET', 'POST', 'COOKIE', 'SESSION', 'REQUEST', 'SERVER' ) ) ? $source : 'REQUEST';
		$type = in_array( $type, array( 'i', 'u', 'f', 's', 'b' ) ) ? $type : 's';

		if ( $isself == true ) {
			$return = $var;
		} else if ( $source == 'REQUEST' ) {
			isset( $_REQUEST[$var] ) && $return = $_REQUEST[$var];
		} else if ( $source == 'GET' ) {
			isset( $_GET[$var] ) && $return = $_GET[$var];
		} else if ( $source == 'POST' ) {
			isset( $_POST[$var] ) && $return = $_POST[$var];
		} else if ( $source == 'COOKIE' ) {
			isset( $_COOKIE[$var] ) && $return = $_COOKIE[$var];
		} else if ( $source == 'SESSION' ) {
			isset( $_SESSION[$var] ) && $return = $_SESSION[$var];
		} else if ( $source == 'SERVER' ) {
			isset( $_SERVER[$var] ) && $return = $_SERVER[$var];
		} else {
			$return = false;
		}

		switch ( $type ) {
			case 'i': //integer
			settype( $return, 'integer' );
			break;
			case 'u': //无符号 integer
			settype( $return, 'integer' );
			$return = $return < 0 ? -$return : $return;
			break;
			case 'f': //小数
			settype( $return, 'float' );
			break;
			case 's':
				settype( $return, 'string' );
				$return = trim( nl2br( $return ) );
				$return = $allowhtml == true ? $return : strip_tags( $return, '<br />' ); //html代码
				$return = $sqlsafe == true ? self::sqlsafeparse( $return ) : $return;
				$return = !@get_magic_quotes_gpc() ? addslashes( $return ) : $return;
				break;
			case 'b':
				settype( $return, 'boolean' );
				break;
			default:
				$return = false;
		}

		return $return;
	}

	/**
	 * 过滤输入的负数
	 *
	 * @param int $num
	 * @return int
	 */
	function uint( $num ) {
		return max( 0, (int)$num );
	}

	/**
	 * 过滤SQL敏感词与符号，防止SQL注入攻击
	 *
	 * @param string $string 需要外部输入的变量
	 * @return string
	 */
	static function sqlsafeparse ( $string ) {
		$aWords = array ( 'select','update','insert','delete','handler','load',
		'infile','replace','truncate','alter','create','drop',
		'rename','grant','revoke','reload',);

		return trim( str_ireplace( $aWords, '*', $string ) );
	}

	/**
	 * 检查邮件地址是否合法
	 */
	function checkEmail( $email ) {
		return eregi( '^([_a-z0-9]([\._a-z0-9-])*)@([a-z0-9]{2,}(\.[a-z0-9-]{2,})*\.[a-z]{2,3})$', $email );
	}

	/**
	 * 获取用户的注册IP的地址信息
	 * @var string $ip 指定要得到地址信息的IP
	 * @return false 或者 array[0] 省或者直辖市 array[1]市或者地区或者空
	 */
	function getclientaddr($ip = '') {
		$clientaddr = '';
		$clientaddr = ( $ip == '' ) ? convertip( func::getclientip() ) : convertip( $ip );
		if ( strpos( $clientaddr, '-' ) ) {
			$clientaddr = substr( $clientaddr, 0, strpos( $clientaddr, '-' ) );
			$clientaddr = explode( ' ', trim( str_ireplace( array('省','市','自治区'), ' ', $clientaddr ) ) );
			return $clientaddr;
		} else {
			return false;
		}
	}

	//获取用户的IP
	static function getclientip() {
		$onlineip = '';
		if(getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')) {
			$onlineip = getenv('HTTP_CLIENT_IP');
		} elseif(getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')) {
			$onlineip = getenv('HTTP_X_FORWARDED_FOR');
		} elseif(getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')) {
			$onlineip = getenv('REMOTE_ADDR');
		} elseif(isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
			$onlineip = $_SERVER['REMOTE_ADDR'];
		}
		return $onlineip;
	}

	//将IP信息转化为( 地址 - ISP信息 )
	function convertip($ip) {
		global $cfg;
		$return = '';

		if(preg_match("/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/", $ip)) {

			$iparray = explode('.', $ip);

			if($iparray[0] == 10 || $iparray[0] == 127 || ($iparray[0] == 192 && $iparray[1] == 168)
			|| ($iparray[0] == 172 && ($iparray[1] >= 16 && $iparray[1] <= 31))) {
				$return = 'LAN';
			} elseif($iparray[0] > 255 || $iparray[1] > 255 || $iparray[2] > 255 || $iparray[3] > 255) {
				$return = 'Invalid IP Address';
			} else {
				$tinyipfile = $cfg['basePath'].'data/tinyipdata.dat';
				$fullipfile = $cfg['basePath'].'data/wry.dat';
				if(@file_exists($tinyipfile)) {
					$return = convertip_tiny($ip, $tinyipfile);
				} elseif(@file_exists($fullipfile)) {
					$return = convertip_full($ip, $fullipfile);
				}
			}
		}

		return $return;

	}

	//使用tiny版数据库得到地址信息
	function convertip_tiny($ip, $ipdatafile) {
		global $objCache;

		static $fp = NULL, $offset = array(), $index = NULL;

		$ipdot = explode('.', $ip);
		$ip    = pack('N', ip2long($ip));

		$ipdot[0] = (int)$ipdot[0];
		$ipdot[1] = (int)$ipdot[1];

		$objCache->connect();
		$indexKey = md5( 'ip_database_index');
		$offsetKey = md5( 'ip_database_offset');
		if( ! $index = $objCache->get($indexKey) && ! $offset = $objCache->get($offsetKey)) {
			if($fp === NULL && $fp = @fopen($ipdatafile, 'rb')) {
				$offset = unpack('Nlen', fread($fp, 4));
				$index  = fread($fp, $offset['len'] - 4);

				$objCache->set($indexKey, $index, 0, true);
				$objCache->set($offsetKey, $offset, 0, true);

			} elseif($fp == FALSE) {
				return  'Invalid IP data file';
			}
		}

		$length = $offset['len'] - 1028;
		$start  = unpack('Vlen', $index[$ipdot[0]		 * 4] . $index[$ipdot[0]		 * 4 + 1] . $index[$ipdot[0]		 * 4 + 2] . $index[$ipdot[0]		 * 4 + 3]);

		for ($start = $start['len']		 * 8 + 1024; $start < $length; $start += 8) {

			if ($index{$start} . $index{$start + 1} . $index{$start + 2} . $index{$start + 3} >= $ip) {
				$index_offset = unpack('Vlen', $index{$start + 4} . $index{$start + 5} . $index{$start + 6} . "\x0");
				$index_length = unpack('Clen', $index{$start + 7});
				break;
			}
		}

		fseek($fp, $offset['len'] + $index_offset['len'] - 1024);
		if($index_length['len']) {
			return fread($fp, $index_length['len']);
		} else {
			return 'Unknown';
		}
	}

	function redirect( $url, $target = '_top' ) {
		header( "Location: $url" );
		echo "<script>window.open( '$url', '$target');</script>";
		exit;
	}

	/**
	 * 中文字符串截取函数
	 *
	 * @param string $string 要截取的字符串
	 * @param int $cutlen 截取的启示位置
	 * @param string $endtag 字符串结束标签
	 * @param string $coding 字符串编码
	 * @return string
	 */
	static function c_substr( $string, $cutlen, $endtag = '', $coding = 'utf-8' ) {
		$length = strlen($string); //总长度
		if($length <= $cutlen) {   //没超长则全部返回
			return $string;
		} else {
			$startid = 0;
			/* 如果是UTF8编码 */
			if( $coding == 'utf-8' ) {
				$endid = $ordid = $cuts = 0;
				while ($endid < $length) {
					$ordno = ord($string[$endid]);
					if($ordno == 9 || $ordno == 10 || (32 <= $ordno && $ordno <= 126)) {
						$ordid = 1; $endid++; $cuts++;
					}
					elseif(194 <= $ordno && $ordno <= 223) {
						$ordid = 2; $endid += 2; $cuts += 2;
					}
					elseif(224 <= $ordno && $ordno < 239) {
						$ordid = 3; $endid += 3; $cuts += 2;
					}
					elseif(240 <= $ordno && $ordno <= 247) {
						$ordid = 4; $endid += 4; $cuts += 2;
					}
					elseif(248 <= $ordno && $ordno <= 251) {
						$ordid = 5; $endid += 5; $cuts += 2;
					}
					elseif($ordno == 252 || $ordno == 253) {
						$ordid = 6; $endid += 6; $cuts += 2;
					}
					else {
						$endid++;
					}
					if ($cuts >= $cutlen) {
						break;
					}
				}
				if ($cuts >= $cutlen) {
					$endid -= $ordid;
				}
			} else { /* GBK,BIG5编码 */
				$endid = 0;
				for ($i=0;$i<$cutlen-2;$i++) {
					if (ord($string[$i]) > 127)	{
						$endid += 2;
						$i++;
					}
					else {
						$endid++;
					}
				}
			} /* 返回的字符串 */
			return substr($string,$startid,$endid).$endtag;
		}
	}
	
	/**
	 * 显示一个选择对话框，可以自定义显示的文字，以及两个的链接的文字及地址
	 *
	 * @param string $msg
	 * @param array $case1 : 第一个链接 $case1[0].链接文字 $case1[1].链接地址
	 * @param array $case2 : 第二个链接 $case2[0].链接文字 $case2[1].链接地址
	 */
	function showerr( $msg, $case1 = '', $case2 = '' ) {
		$htmlhead  = "<html>\r\n<head>\r\n<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\" />\r\n";
		$htmlhead .= "<style type=\"text/css\">\r\n
			body{text-align:center}
			ul { margin-left:5px; line-height: 40px; list-style:none; text-indent: 50px; }
			p{text-align:center;font-weight:700;font-size:16px;}
			a:link,a:visited{color:#01627F;text-decoration:none}
			a:hover{color:red;text-decoration:underline}
			.showmsg{
			margin: 0 auto; padding: 10px 15px 10px 0; height:auto; line-height:26px; width:473px; 
			text-align:left; color:#FF0000; border:#C4D4EA 1px solid;}
			</style>\r\n";
		$htmlhead .= "<base target=\"_self\" />\r\n</head>\r\n<body>";
		$htmlfoot  = "\r\n</body>\r\n</html>";

		if ( empty( $case1 ) ) {
			$url  = '';
		} else {
			$url  = "<p><a href=\"{$case1[1]}\">{$case1[0]}</a>　　";       //第一个链接
		}
		if ( empty( $case2 ) ) {
			$url .= '';
		} else {
			$url .= "<a href=\"{$case2[1]}\">{$case2[0]}</a></p>";          //第二个链接
		}
		$url .= "<p><a href=\"javascript:history.go(-1)\">返回上一页</a></p>";  //返回上一页链接
		$htmlbody = "<div class='showmsg'><ul><li><h5>$msg</h5></ul></li>$url</div>";
		$msg  = $htmlhead.$htmlbody.$htmlfoot;
		echo $msg;
		exit;
	}
}